package main
import (
	"fmt"
	_"math"
	"time"
)
//要求统计1-8000的数字中，哪些是素数？5个协程3个管道
//思路分析看images/5.png

func main(){
	numchan := make(chan int,1000)
	reschan := make(chan int,20000)
	exitchan :=make(chan bool,4) //存四个协程的完成结果

	start := time.Now().UnixNano() ///测这次执行的时间

	//启动存数据协程
	go PutNumber(numchan)
	//开启四个协程来从numchan管道取出数据并且判断是否素数,结果放入reschan管道中
	for i:=0;i<4;i++{
		go PrimeNum(numchan,reschan,exitchan)
	}

	//判断以上的协程是否执行完？
	go func(){   
		for i:=0;i<4;i++{
			<-exitchan
		}
		end := time.Now().UnixNano()
		fmt.Println("本次通过协程所消耗的时间：",end-start)
		//协程已经执行完，可以关闭res管道了！
		close(reschan)
	}()

	for {
		_,ok := <- reschan
		if !ok{
			break
		}
		//fmt.Println("素数：",res)
	}

	fmt.Println("main函数执行结束")
}

/*
func main(){  //普通for循环来计算素数
	start := time.Now().Unix() ///测这次执行的时间

	for num:=1;num<=80000;num++{
		flag := true
		for i := 2;i < num;i++{  // i < int(math.Sqrt(float64(num))) 这个判断条件会更快
			if num % i == 0{
				flag = false
				break
			}
		}
		if flag{

		}
	}
	end := time.Now().Unix()
	fmt.Println("本次通过普通方法没有使用协程所消耗的时间：",end-start)
}

*/

//存入1-8000个数
func PutNumber(numchan chan int){
	for i:=1;i<=80000;i++{
		numchan <- i
	}
	close(numchan)
}


func PrimeNum(numchan chan int,reschan chan int,exitchan chan bool){
	var flag bool
	for {
		flag = true
		num,ok := <- numchan
		if !ok{
			break
		}
		for i:=2;i < num ;i++{  //int(math.Sqrt(float64(num)))
			if num % i == 0{
				flag = false
				break
			}
		}
		if flag{
			reschan <- num
		}
	}
	fmt.Println("本协程已经取不到了数据了，要退出了！")
	exitchan <- true
}